#!/usr/bin/env bash
# author    : azureQAQ
# version   : v-0.2

filePath="${HOME}/homedst"

# shellFolder=$(cd "$(dirname "$0")"; pwd)
shellFolder=$(cd "$(dirname "$(realpath $0)")"; pwd)

cmdPath="${filePath}/steamcmd"
cmdFile="${cmdPath}/steamcmd.sh"

gamePath="${filePath}/dst"
gameFile="${gamePath}/bin/dontstarve_dedicated_server_nullrenderer"

modFile="${gamePath}/mods/dedicated_server_mods_setup.lua"

dividing="================================================================================"

# echo染色
function Color_echo() {
    case ${1} in
        1)	# red
            echo -e "\033[31m$2\033[0m";;
        2)	# yellow
            echo -e "\033[33m$2\033[0m";;
        3)	# green
            echo -e "\033[32m$2\033[0m";;
        4)  # 红色警告 退出
            echo -e "\033[31m$2\033[0m" && exit 1;;
        *)
            echo "$2"
            ;;
    esac
}

# 安装依赖库
function SysPreps() {
    sudo apt-get update         1>/dev/null
    # x64
    sudo apt-get install -y libstdc++6:i386 libgcc1:i386 libcurl4-gnutls-dev:i386 libsdl2-2.0-0:i386 screen ripgrep sd
    # sudo apt-get install -y libstdc++6:i386 libgcc1:i386 libcurl4-gnutls-dev:i386 libsdl2-2.0-0:i386 screen    1>/dev/null
    # x32
    # sudo apt-get install -y libstdc++6 libgcc1 libcurl4-gnutls-dev libsdl2-2.0-0:i386 screen
    # sudo apt-get install -y libstdc++6 libgcc1 libcurl4-gnutls-dev libsdl2-2.0-0:i386 screen                   1>/dev/null

}

function GamePreps() {
    if [ ! -d "${gamePath}" ]; then
        Color_echo 2 "游戏未安装，安装..."
        GameUpdate || Color_echo 4 "steamcmd未安装！"
    fi
}

function GameUpdate() {
    # steamcmd 监测
    WaittoExit
    JustExit
    CmdPreps
    # 校验完整性
    Color_echo 3 "[安装/更新]：[1].正式版 [2].测试版"
    read -r input_update
    case ${input_update} in
        1)
            ${cmdFile} +force_install_dir "${gamePath}" +login anonymous +app_update 343050 validate +quit
            ;;
        2)
            ${cmdFile} +force_install_dir "${gamePath}" +login anonymous +app_update 343050 -beta cavesbeta validate +quit
            ;;
        *)
            Color_echo 1 "非法输入"
            ;;
    esac
}

function CmdPreps() {
    if [ ! -d "${cmdPath}" ]; then
    Color_echo 2 "steamcmd未安装，安装..."
        mkdir -p ${cmdPath}
        cd ${cmdPath}
        wget "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz"       1>/dev/null
        tar -xvzf "steamcmd_linux.tar.gz"                                                   1>/dev/null
        rm -r "steamcmd_linux.tar.gz"
    fi
}

function AddMod() {
    rg 'workshop\-\d+' "${HOME}/.klei/DoNotStarveTogether/${1}_Cluster/Master/modoverrides.lua" -o --no-line-number | sd 'workshop\-' 'ServerModSetup("' | sd '$' '")' | rg '^S' > ${modFile}
    Color_echo 3 "mods已写入配置文件"
}

function ServerStart() {
    GamePreps
    RemoteCmd 1
    cd "${gamePath}/bin" || Color_echo 1 "饥荒安装失败，请重试。"
    Color_echo 3 "存档：[1-?]"
    read -r input_cluster


    if [ ${input_cluster} -gt 0 ] 2>/dev/null
    then
        echo 0 >/dev/null
    else
        Color_echo 1 "非法输入"
        return
    fi

    Color_echo 3 "启动：[1].地面+洞穴 [2].仅地面"
    read -r input_mod

    # 等待服务器关闭
    WaittoExit
    JustExit

    # 安装Mods
    AddMod ${input_cluster}

    case ${input_mod} in
        1)
            screen -dmS "Master_DST" "${gameFile}" -cluster "${input_cluster}"_Cluster -shard Master

            GetmasterPid

            screen -dmS "Caves__DST" "${gameFile}" -cluster "${input_cluster}"_Cluster -shard Caves -monitor_parent_process "${masterpid}"
            ;;
        2)
            screen -dmS "Master_DST" "${gameFile}" -cluster "${input_cluster}"_Cluster -shard Master
            ;;
        *)
            Color_echo 1 "非法输入"
            ;;
    esac
    Color_echo 3 "服务器已经后台启用"
    CountScreen
    Color_echo 2 "目前服务器数：${screen_num}"
}

function WaittoExit() {
    Color_echo 3 "等待之前的服务器关闭..."
    CountScreen
    if [ ${screen_num} -eq 0 ]; then
        Color_echo 3 "当前未运行服务器"
        return
    fi
    for i in {1..5};
    do
        RemoteCmd 1
        sleep 2
        CountScreen
        if [ ${screen_num} -ne 0 ]; then
            Color_echo 2 "第${i}次检测"
        else
            Color_echo 3 "服务器已经关闭"
            return
        fi
    done
    Color_echo 1 "服务器未关闭，请稍后再试或者强制关闭"
}

function JustExit() {
    CountScreen
    Color_echo 2 "目前服务器数：${screen_num}"
    if [ ${screen_num} -ne 0 ]; then
        RemoteCmd 3
        Color_echo 1 "强制关闭服务器"
        CountScreen
        Color_echo 2 "目前服务器数：${screen_num}"
    fi
}

function RemoteCmd() {
    # 与饥荒服务器通信
    case ${1} in
        1)
            screen -S "Master_DST" -p 0 -X stuff $"c_shutdown(true)\n"      1>/dev/null
            ;;
        2)
            screen -S "Master_DST" -p 0 -X stuff $"c_announce(\"$2\")\n"    1>/dev/null
            ;;
        3)
            screen -X -S "Master_DST" quit                                  1>/dev/null
            screen -X -S "Caves__DST" quit                                  1>/dev/null
            ;;
        *)
            Color_echo 1 "非法输入"
            ;;
    esac
}

screen_num=0
function CountScreen() {
    screen_num=$(ls /run/screen/S-"$(whoami)" | grep -c "DST")
}

function GetmasterPid() {
    pidstr=$(ls /run/screen/S-"$(whoami)" | grep "Master_DST")
    # 5237.Master_dst 5243.Caves__dst
    masterpid="${pidstr%.Master*}"
}

function GetcavesPid() {
    pidstr=$(ls /run/screen/S-"$(whoami)" | grep "Caves__DST")
    # 5237.Master_dst 5243.Caves__dst
    cavespid="${pidstr%.Caves*}"
}

function CheckFile() {
    # 检查必备文件
    echo 0
}

function FilesBackup() {
    Color_echo 3 "要备份的存档：[1-?]"
    read -r input_filebackup

    if [ -d "${HOME}/.klei/DoNotStarveTogether/${input_filebackup}_Cluster" ]; then
        cd "${HOME}/.klei/DoNotStarveTogether"
        tar -czf ${input_filebackup}_Cluster.tar.gz ${input_filebackup}_Cluster
        Color_echo 3 "备份完成"
    else
        Color_echo 2 "未找到对应存档"
    fi
}

function FilesRecovery() {
    Color_echo 3 "选择要恢复的存档：[1-?]"
    read -r input_filerec
    if [ -f "${HOME}/.klei/DoNotStarveTogether/${input_filerec}_Cluster.tar.gz" ]; then
        if [ -d "${HOME}/.klei/DoNotStarveTogether/${input_filerec}_Cluster" ]; then
            rm -r "${HOME}/.klei/DoNotStarveTogether/${input_filerec}_Cluster"
        fi
        
        cd "${HOME}/.klei/DoNotStarveTogether"
        tar -xzf "${HOME}/.klei/DoNotStarveTogether/${input_filerec}_Cluster.tar.gz"
        Color_echo 3 "恢复完成"
    else
        Color_echo 2 "未找到对应存档"

    fi
}

function FilesDel() {
    Color_echo 2 "请输入要删除的存档[1-?](PS.这会停止所有服务器，即便是无关存档)"
    read -r input_filedel

    if [ -d "${HOME}/.klei/DoNotStarveTogether/${input_filedel}_Cluster" ]; then
        RemoteCmd 3
        cd "${HOME}/.klei/DoNotStarveTogether/${input_filedel}_Cluster"
        DelFile "./Master/backup"
        DelFile "./Master/save"
        DelFile "./Master/server_chat_log.txt"
        DelFile "./Master/server_log.txt"
        # rm -r "./Master/backup" "./Master/save" "./Master/server_chat_log.txt" "./Master/server_log.txt"    >/dev/null
        DelFile "./Caves/backup"
        DelFile "./Caves/save"
        DelFile "./Caves/server_chat_log.txt"
        DelFile "./Caves/server_log.txt"
        # rm -r "./Caves/backup" "./Caves/save" "./Caves/server_chat_log.txt" "./Caves/server_log.txt"        >/dev/null
        Color_echo 2 "对应存档已经删除"
    else
        Color_echo 2 "未找到对应存档"

    fi
}

function DelFile() {
    if [ -d "${1}" ]; then
        rm -r "${1}"
    fi
    if [ -f "${1}" ]; then
        rm -r "${1}"
    fi
}

function AutoUpdate() {
    Color_echo 3 "开始自动更新检测程序"
}

function Py_Preps() {
    cd $shellFolder
    source ./venv/bin/activate
}

function ProFunction() {
    Color_echo 3 "[0].更新脚本 [1].高级功能环境准备"
    Color_echo 3 "[2].需要更新？ [3].存档人数统计"
    # Color_echo 3 "[2].自动更新服务器"
    read -r input_pro
    case ${input_pro} in
        0)
            SrcUpdate
            ;;
        1)
            sudo apt-get update      1>/dev/null
            cd ${shellFolder}
            sudo apt-get install python3
            sudo apt-get install python3-venv

            if [ ! -d "./venv" ]; then
                python3 -m venv venv
            fi

            source ./venv/bin/activate
            pip install -U pip                  1>/dev/null
            pip install -r requirements.txt     1>/dev/null
            deactivate
            ;;
        
        2)
            Py_Preps
            python "./getdstversion.py"



            deactivate
            ;;
        3)
            Color_echo 3 "请输入存档号:"
            read -r input_chat
            chat_file="${HOME}/.klei/DoNotStarveTogether/${input_chat}_Cluster/Master/server_chat_log.txt"
            if [ -f "${chat_file}" ]; then
                # 加入的人数
                join_num=`cat ${chat_file} | grep "\[Join Announcement\]" | wc -l`
                leave_num=`cat ${chat_file} | grep "\[Leave Announcement\]" | wc -l`
                stay_num=$((join_num-leave_num))
                Color_echo 3 "存档：${input_chat} 现人数：${stay_num}"
                # 皮肤数
                skin_num=`cat ${chat_file} | grep "\[Skin Announcement\]" | wc -l`
                Color_echo 3 "存档：${input_chat} 皮肤数：${skin_num}"
                # 对话数
                taik_num=`cat ${chat_file} | grep "\[Say\]" | wc -l`
                Color_echo 3 "存档：${input_chat} 对话数：${taik_num}"

            else
                Color_echo 2 "你输入存档：${chat_file} 不存在"
                return 0
            fi
            ;;

        *)
            Color_echo 1 "非法输入"
            ;;

    esac
}

function SrcUpdate() {
    cd ${shellFolder}
    git reset --hard && \
    git switch master && \
    git pull && \
    chmod -R 760 "./run.sh"

    if [ ! -L "${HOME}/run" ]; then
        ln -s "${shellFolder}/run.sh" "${HOME}/run"
    fi
    if [ ! -L "${shellFolder}/version.txt" ]; then
        ln -s "${gamePath}/version.txt" "${shellFolder}/version.txt" || Color_echo 2 "为保证部分高级功能可用，请安装游戏后再执行此功能一次"
    fi
}

function UninstallAll() {
    Color_echo 1 "确认删除所有？"
    Color_echo 1 "包括：本脚本所在文件夹，安装的游戏，steamcmd，不包括存档"
    Color_echo 1 "[1].确认 [2].取消"
    read -r input_del
    case ${input_del} in
        1)
            RemoteCmd 3
            Color_echo 1 "删除steamcmd、饥荒..."
            rm -r "${filePath}"         1>/dev/null
            Color_echo 1 "删除Steam..."
            rm -r "${HOME}/Steam"       1>/dev/null
            Color_echo 1 "删除本工具..."
            rm -r ${shellFolder}
            Color_echo 1 "删除 ~/run"
            if [ -L "${HOME}/run" ]; then
                rm -r "${HOME}/run"
            fi
            ;;
        
        *)
            Color_echo 3 "取消"

    esac
}

# ======================================
clear
Color_echo 3 "${dividing}"
Color_echo 3 "[0].运行库安装"
Color_echo 3 "[1].启动 [2].更新 [3].保存并关闭"
Color_echo 3 "[4].直接关闭 [5].删除存档"
Color_echo 3 "[6].备份存档 [7].恢复备份"
Color_echo 3 "[8].删除备份 [9].高级功能"

read -r input_start
case ${input_start} in
    0)
        Color_echo 3 "运行库[安装/更新]"
        SysPreps
        ;;
    1)
        Color_echo 3 "启动游戏..."
        ServerStart
        ;;
    2)
        Color_echo 3 "更新游戏..."
        GameUpdate
        ;;
    3)
        Color_echo 3 "保存并关闭服务器"
        WaittoExit
        ;;
    4)
        Color_echo 2 "直接关闭服务器"
        CountScreen
        if [ ${screen_num} -eq 0 ]; then
            Color_echo 3 "当前未运行服务器"
        else
            RemoteCmd 3
            Color_echo 2 "直接关闭服务器，当前进度不会保存"
        fi
        ;;
    5)
        Color_echo 2 "删除存档"
        FilesDel
        ;;
    6)
        Color_echo 3 "备份存档"
        FilesBackup
        ;;
    7)
        Color_echo 3 "恢复存档"
        FilesRecovery
        ;;
    8)
        Color_echo 2 "删除备份"
        Color_echo 1 "building..."
        ;;
    9)
        Color_echo 3 "高级功能"
        ProFunction
        ;;
    *)
        Color_echo 1 "非法输入"
        ;;
esac
